﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Persistencia;
using GestorDeFlotasModelo.Entities;
using Persistencia.Interfaces;
using System.Data.SqlClient;

namespace GestorDeFlotasModelo.Factorias
{
    public class FactoriaCliente : Factoria, IIdentityFactory
    {
          private FactoriaCliente(TransaccionBase tran)
            : base(tran)
        {
        }
        

        public override string NombreTabla
        {
            get { return " NUESTRA_RUBIA_ES_MEJOR.Cliente "; }
        }

        protected override IPersistibleModelo NuevoPersistible(HashTableNCSensitive htsNc)
        {
            return new Cliente();
        }

        protected override string Id(HashTableNCSensitive hts)
        {
            return hts["Cliente_Id"].ToString();
        }

        protected override HashTableNCSensitive ParametrosClave()
        {
            HashTableNCSensitive parameters = new HashTableNCSensitive();
            parameters.Add("Cliente_Id", null);
            return parameters;

        }

        protected override HashTableNCSensitive ParametrosNoClave()
        {
            HashTableNCSensitive parameters = new HashTableNCSensitive();
            parameters.Add("Cliente_Nombre", null);
            parameters.Add("Cliente_Apellido", null);
            parameters.Add("Cliente_Dni", null);
            parameters.Add("Cliente_Telefono", null);
            parameters.Add("Cliente_Mail", null);
            parameters.Add("Cliente_Direccion", null);
            parameters.Add("Cliente_CodiPostal", null);
            parameters.Add("Cliente_Fecha_Nac", null);
            parameters.Add("Cliente_Habilitado", null);
            return parameters;
        }


        protected override Predicate<IPersistibleModelo> FiltroXId(string id)
        {
            return delegate(IPersistibleModelo iPer)
            {
                return ((Cliente)iPer).Id == long.Parse(id);
            };
        }

        public List<Cliente> SelectTodosHabilitados()
        {
            SqlCommand comm = new SqlCommand();
            string consulta = "SELECT * FROM " + this.NombreTabla + " WHERE Cliente_Habilitado=1";
            comm.CommandText = consulta;
            return base.Select<Cliente>(comm, delegate(IPersistibleModelo iPer) { return ((Cliente)iPer).Habilitado; });
        }

        public int GetCountTelefonos(long telefono)
        {
            SqlCommand comm = new SqlCommand();
            string consulta = "SELECT * FROM " + this.NombreTabla + " WHERE Cliente_Telefono=@telefono";
            comm.Parameters.AddWithValue("@telefono", telefono);
            comm.CommandText = consulta;

            return base.Select<Cliente>(comm, delegate(IPersistibleModelo iPer) { return ((Cliente)iPer).Telefono==telefono; }).Count;
        }

        public List<Cliente> SelectPorFiltros(string name, string lastName, long dni)
        {
            SqlCommand comm = new SqlCommand();
            string nameFilter = string.Empty;
            string lastNameFilter = string.Empty;
            string dniFilter = string.Empty;

            if (!string.IsNullOrEmpty(name))
            {
                nameFilter = "Cliente_Nombre LIKE '%@Cliente_Nombre%'";
                comm.Parameters.AddWithValue("@Cliente_Nombre", name);
            }
            if (!string.IsNullOrEmpty(lastName))
            {
                lastNameFilter = ((!string.IsNullOrEmpty(nameFilter)) ? " OR " : string.Empty) + "Cliente_Apellido LIKE '%@Cliente_Apellido%'";
                comm.Parameters.AddWithValue("@Cliente_Apellido", lastName);
            }
            if (dni > 0)
            {
                dniFilter = ((!string.IsNullOrEmpty(nameFilter) || !string.IsNullOrEmpty(lastNameFilter)) ? " OR " : string.Empty) + "Cliente_Dni = @Cliente_Dni";
                comm.Parameters.AddWithValue("@Cliente_Dni", dni);
            }
            string filters = nameFilter + lastNameFilter + dniFilter; 
            comm.CommandText = "SELECT * FROM " + this.NombreTabla + ((!String.IsNullOrEmpty(filters)) ? " WHERE " + filters : string.Empty);

            List<Cliente> clientes = base.Select<Cliente>(comm, delegate(IPersistibleModelo iPer) {

                bool cumple = true;
                if (!String.IsNullOrEmpty(name) && !((Cliente)iPer).Nombre.ToLower().Contains(name.ToLower()))
                    cumple = false;

                if (!String.IsNullOrEmpty(lastName) && !((Cliente)iPer).Apellido.ToLower().Contains(lastName.ToLower()))
                    cumple = false;

                if (dni > 0 && ((Cliente)iPer).Dni != dni)
                    cumple = false;

                return cumple;
            });

            clientes.Sort(delegate(Cliente c1, Cliente c2)
            {
                return c1.Id.CompareTo(c2.Id);
            });

            if (clientes.Count > 0)
                return clientes;
            else
                return new List<Cliente>();
        }

        public List<Cliente> MejorCliente(string desde, string hasta)
        {
            SqlCommand comm = new SqlCommand();
            string consulta = "SELECT TOP 5 C.Cliente_Dni, C.Cliente_Apellido,C.Cliente_Nombre, C.Cliente_Telefono, C.Cliente_Fecha_Nac, Sum(F.Factura_Importe) Recaudacion FROM NUESTRA_RUBIA_ES_MEJOR.Cliente  C JOIN NUESTRA_RUBIA_ES_MEJOR.Factura F ON";
            consulta += " C.Cliente_Id=F.Factura_Cliente where f.Factura_Fecha_Inicio>=@Desde AND f.Factura_Fecha_Fin<=@Hasta GROUP BY C.Cliente_Dni, C.Cliente_Apellido,C.Cliente_Nombre, C.Cliente_Telefono, C.Cliente_Fecha_Nac ";
            consulta += " ORDER BY Recaudacion DESC";
            comm.CommandText = consulta;
            comm.Parameters.AddWithValue("@Desde", DateTime.Parse(desde));
            comm.Parameters.AddWithValue("@Hasta", DateTime.Parse(hasta));
            List<HashTableNCSensitive> resultado = this.Transaccion.EjecutarComando(comm, 5);
            List<Cliente> cliente = new List<Cliente>();
            foreach (HashTableNCSensitive row in resultado)
            {
                Cliente c = new Cliente();
                ((IPersistibleModelo)c).Cargar(row);
                cliente.Add(c);
            }
            return cliente;
        }

        public Cliente Nuevo(string nombre, string apellido, string codigoPostal, string direccion, long dni, long telefono, DateTime fechaNacimiento, string mail)
        {
            Cliente cli = new Cliente();
            cli.Habilitado = true;
            cli.Apellido = apellido;
            cli.CodigoPostal = codigoPostal;
            cli.Direccion = direccion;
            cli.Dni = dni;
            cli.FechaNacimiento = fechaNacimiento;
            cli.Mail = mail;
            cli.Nombre = nombre;
            cli.Telefono = telefono;

            base.Agregar(cli);
            return cli;
        }
    }
}
